package com.jinmdz.fmis.api.api.service;

import com.jinmdz.fmis.api.api.model.common.BusinessCharges;
import com.jinmdz.fmis.api.api.model.common.DataCodeData;
import com.jinmdz.fmis.api.api.model.common.IdData;
import com.jinmdz.fmis.api.api.model.common.IdVersionData;
import com.jinmdz.fmis.api.api.model.cremation.*;
import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.api.constant.MessageConst;
import com.jinmdz.fmis.api.model.config.dictionary.BusinessLogCode;
import com.jinmdz.fmis.api.model.config.dictionary.CremationStatusCode;
import com.jinmdz.fmis.api.model.config.dictionary.DictionaryCode;
import com.jinmdz.fmis.api.model.config.dictionary.OperationLogCode;
import com.jinmdz.fmis.api.model.system.UserItem;
import com.jinmdz.fmis.api.wrapper.ChargeWrapper;
import com.jinmdz.fmis.api.wrapper.DictionaryWrapper;
import com.jinmdz.fmis.api.wrapper.OperationWrapper;
import com.jinmdz.fmis.common.ext.StringBuilderExt;
import com.jinmdz.fmis.common.util.BeanUtil;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.common.util.DateUtil;
import com.jinmdz.fmis.core.base.BaseResult;
import com.jinmdz.fmis.core.constant.EBusinessType;
import com.jinmdz.fmis.core.constant.EDictCode;
import com.jinmdz.fmis.core.constant.PurposeConst;
import com.jinmdz.fmis.core.exception.ActionException;
import com.jinmdz.fmis.core.util.JacksonUtil;
import com.jinmdz.fmis.dao.dao.*;
import com.jinmdz.fmis.dao.model.charge.ChargeItem;
import com.jinmdz.fmis.dao.model.cremation.AppointmentTimeSegmentCountItem;
import com.jinmdz.fmis.dao.model.cremation.CremationFurnaceViewItem;
import com.jinmdz.fmis.dao.model.cremation.CremationItem;
import com.jinmdz.fmis.dao.model.cremation.CremationViewItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyAgentItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyMemberItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralBusinessViewItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralDeadItem;
import com.jinmdz.fmis.dao.model.service.ServiceItem;
import com.jinmdz.fmis.mapper.entity.ChargeItemEntity;
import com.jinmdz.fmis.mapper.entity.CremationEntity;
import com.jinmdz.fmis.mapper.entity.FuneralBusinessLogEntity;
import com.jinmdz.fmis.mapper.mapper.CremationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

/**
 * 火化CremationService类
 *
 * @author GaoXiangLiang
 * @date 2020-01-20 11:52
 */
@Service("cremationService")
public class CremationService extends BaseService {

    @Resource
    private FuneralBusinessDao funeralBusinessDao;

    @Resource
    private CremationMapper cremationMapper;

    @Resource
    private CremationStatusCode cremationStatusCode;

    @Resource
    private ServiceItemDao serviceItemDao;

    @Resource
    private ChargeItemDao chargeItemDao;

    @Resource
    private CremationDao cremationDao;

    @Resource
    private CremationFurnaceDao cremationFurnaceDao;

    @Resource
    private ChargeWrapper chargeWrapper;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private FuneralDeadDao funeralDeadDao;

    @Resource
    private FamilyMemberDao familyMemberDao;
    @Resource
    private FamilyAgentDao familyAgentDao;
    @Resource
    private DataDictionaryDao dataDictionaryDao;

    @Resource
    private OperationLogCode operationLogCode;

    @Resource
    private OperationWrapper operationWrapper;

    @Resource
    private DictionaryWrapper dictionaryWrapper;

    @Resource
    private BusinessLogCode businessLogCode;

    @Resource
    private CremationTimeSegmentDao cremationTimeSegmentDao;

    @Resource
    private DictionaryCode dictionaryCode;

    /**
     * 根据cremation表中id加载火化任务信息
     *
     * @param data 火化主键
     * @return
     * @author LiCongLu
     * @date 2020-02-15 19:12
     */
    public BaseResult<CremationData> loadCremationWithId(IdData data) {
        Integer loadId = data.getId();

        // 查询业务信息
        CremationViewItem loadItem = cremationDao.getCremationViewById(loadId);

        if (DataUtil.isNull(loadItem) || DataUtil.isNull(loadItem.getId(), loadItem.getVersion())) {
            return failure("主键错误，不存在此业务信息");
        }
        CremationData loadData = loadCremationData(loadItem);
        // 返回响应结果
        return successData(loadData);
    }

    /**
     * 获取业务费用等数据
     *
     * @param loadItem 已加载数据
     * @return
     * @author LiCongLu
     * @date 2020-02-16 11:56
     */
    private CremationData loadCremationData(CremationItem loadItem) {
        // 创建响应实体，并赋值
        CremationData loadData = BeanUtil.copy2Bean(loadItem, new CremationData());

        // 获取业务费用及物品服务
        loadData.setCharges(new BusinessCharges());

        ChargeItem businessCharge = chargeItemDao.getChargeItemById(loadItem.getChargeId());
        loadData.getCharges().setBusinessCharge(businessCharge);

        // 业务费用主键
        Integer businessChargeId = businessCharge != null ? businessCharge.getId() : 0;

        ArrayList<ChargeItem> goodsServices = chargeItemDao.listChargeItemByRandomCode(loadItem.getBusinessCode(), loadItem.getRandomCode(), businessChargeId);
        loadData.getCharges().setGoodsServices(goodsServices);
        //设置文本值
        dictionaryWrapper.resetDataText(loadData);
        return loadData;
    }

    /**
     * 保存火化信息到cremation表中
     *
     * @param data 火化请求数据
     * @return
     * @author LiCongLu
     * @date 2020-02-15 19:12
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<CremationData> saveCremation(UserItem userItem, CremationData data) throws ActionException {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            throw exception(MessageConst.NO_FUNERAL_CODE);
        }

        Integer id = data.getId();
        //判断逝者是遗体类型时，是否存在重复身份证号的火化类型是遗体的记录
        // 验证火化类型(遗体类型)是遗体时验证证件号码是否重复
        Integer deadId = funeralItem.getDeadId();
        //逝者
        FuneralDeadItem funeralDeadItem = funeralDeadDao.getFuneralDeadByBusinessCode(businessCode);
        //家属
        FamilyMemberItem familyMemberItem = familyMemberDao.getFamilyMemberByBusinessCode(businessCode);
        //承办
        FamilyAgentItem familyAgentItem = familyAgentDao.getFamilyAgentByBusinessCode(businessCode);
        //火化类型是遗体时
        if (DataUtil.equals(data.getCremationTypeCode(), dictionaryCode.getCremationTypeYiTi())) {
            //遗体证件不存在，不验证
            if (DataUtil.valid(funeralDeadItem.getCertificateNo())) {
                String businessCodeOld = funeralDeadDao.hasBusinessCodeForCertificateNo(funeralDeadItem.getCertificateNo(), dictionaryCode.getCremationTypeYiTi(), deadId);
                if (DataUtil.valid(businessCodeOld)) {
                    throw exception("火化类型同为遗体的存在重复证件号码");
                }
            }

            // 与家属证号码比较
            if (DataUtil.valid(familyMemberItem.getCertificateNo())) {
                if (DataUtil.equals(funeralDeadItem.getCertificateNo(), familyMemberItem.getCertificateNo())) {
                    throw exception("逝者证件号码不能与家属证件号码相等");
                }
            }

            // 与承办人证件号码比较
            if (DataUtil.noNullOrEmpty(familyAgentItem)
                    && DataUtil.valid(familyAgentItem.getCertificateNo())) {
                if (DataUtil.equals(funeralDeadItem.getCertificateNo(), familyAgentItem.getCertificateNo())) {
                    throw exception("逝者证件号码不能与承办人证件号码相等");
                }
            }
        }
        // 主键不为空
        if (DataUtil.valid(id)) {
            updateCremation(userItem, funeralItem, data);
        } else {
            id = insertCremation(userItem, funeralItem, data);
        }
        return loadCremationWithId(new IdData(id));
    }

    /**
     * 插入火化信息
     *
     * @param userItem    当前帐号
     * @param funeralItem 殡葬业务
     * @param data        新增火化信息
     * @return
     * @author LiCongLu
     * @date 2020-02-15 10:58
     */
    private Integer insertCremation(UserItem userItem, FuneralBusinessViewItem funeralItem, CremationData data) throws ActionException {
        // 创建火化实体
        CremationEntity entity = getEntity(userItem, CremationEntity.class);

        // 覆盖数据
        BeanUtil.copy2Bean(data, entity);

        // 创建业务随机码
        entity.setRandomCode(DataUtil.getUUID());

        // 依照状态等设置默认值
        saveCremationValue(data, entity);

        // 插入业务费用
        ChargeItem businessCharge = data.getCharges().getBusinessCharge();
        businessCharge.setBusinessCode(entity.getBusinessCode())
                .setRandomCode(entity.getRandomCode())
                .setItemNumber(data.getRuleNumber())
                .setItemUnit(data.getRuleUnit())
                .setAsUnsettled(0);

        String dictCode = EDictCode.FURNACE_TYPE.getCode();
        String purpose = PurposeConst.YI_TI_HUO_HUA;
        int chargeId = chargeWrapper.insertBusinessCharge(userItem, businessCharge, dictCode, entity.getFurnaceTypeCode(), purpose, data.getRuleRemark());
        entity.setChargeId(chargeId);

        // 插入物品服务
        ArrayList<ChargeItemEntity> chargeEntities = chargeWrapper.insertGoodsServices(userItem, entity.getBusinessCode(), entity.getRandomCode(), EBusinessType.USE_IN_CREMATION.getType(), data.getCharges().getGoodsServices());

        // 明确激活状态
        entity.setAsActive(1);

        // 新增火化信息
        cremationMapper.insertCremation(entity);
        // 判断保存火化信息结果
        if (DataUtil.invalid(entity.getId())) {
            throw exception("保存火化信息失败");
        }

        // 更新逝者遗体类型
        funeralDeadDao.updateForCremationTypeCode(data.getCremationTypeCode(), funeralItem.getDeadId(), funeralItem.getBusinessCode(), userItem.getId());

        // 添加业务及操作日志
        Integer logTypeCode = operationLogCode.getCremationInsert();
        Integer chargeLogTypeCode = operationLogCode.getChargeInsert();
        saveCremationLog(userItem, funeralItem, data, entity, logTypeCode, chargeLogTypeCode, businessCharge, chargeEntities, null);

        return entity.getId();
    }


    /**
     * 添加火化日志记录
     *
     * @param userItem          当前帐号
     * @param funeralItem       当前业务
     * @param data              请求数据
     * @param entity            数据实体
     * @param logTypeCode       日志记录类型
     * @param chargeLogTypeCode 费用日志类型
     * @param businessCharge    业务费用
     * @param chargeEntities    费用记录
     * @param deleteEntities    删除费用记录
     * @return
     * @author LiCongLu
     * @date 2020-02-25 19:28
     */
    private void saveCremationLog(UserItem userItem, FuneralBusinessViewItem funeralItem
            , CremationData data, CremationEntity entity
            , Integer logTypeCode, Integer chargeLogTypeCode
            , ChargeItem businessCharge, ArrayList<ChargeItemEntity> chargeEntities, ArrayList<ChargeItemEntity> deleteEntities) throws ActionException {

        // 添加业务日志及操作日志
        String businessCode = funeralItem.getBusinessCode();
        Integer typeCode = businessLogCode.getCremationUpdate();
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);

        // 获取新设备信息
        CremationFurnaceViewItem furnaceItem = cremationFurnaceDao.getCremationFurnaceViewById(entity.getFurnaceId());
        String furnaceCode = furnaceItem != null ? furnaceItem.getFurnaceCode() : "";

        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("保存火化信息，业务编码[{0}]，逝者姓名[{1}]，火化设备类型[{2}][{3}]，火化设备编号[{4}]，预约火化日期[{5}]，预约时间段[{6}]，火化状态[{7}]" +
                        " ，火化费用[{8}]，火化（遗体）类型编码[{9}][{10}]，操作人员[{11}]"
                , businessCode, funeralItem.getDeadName()
                , String.valueOf(entity.getFurnaceTypeCode())
                , dictionaryWrapper.getDataText(EDictCode.EQUIPMENT_TYPE, entity.getFurnaceTypeCode())
                , furnaceCode
                , DateUtil.formatPattern10(entity.getAppointmentDate()), entity.getAppointmentTimeSegment()
                , dictionaryWrapper.getDataText(EDictCode.REFRIGERATED_STATE, entity.getProcessStateCode())
                , DataUtil.getPlainString(businessCharge.getItemCharge())
                , String.valueOf(data.getCremationTypeCode())
                , dictionaryWrapper.getDataText(EDictCode.CREMATION_TYPE, data.getCremationTypeCode())
                , userItem.getFullName());

        // 添加日志
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode, builder.toString()
                , JacksonUtil.obj2Json(data), null, JacksonUtil.obj2Json(entity));

        // 累计费用总金额
        if (DataUtil.valid(chargeEntities)) {
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItemEntity chargeEntity : chargeEntities) {
                sumCharge = sumCharge.add(chargeEntity.getItemCharge());
            }
            // 添加物品服务费用日志
            builder.clear();
            builder.format("保存火化信息更新物品服务，业务编码[{0}]，逝者姓名[{1}]，火化费用[{2}]，物品服务总金额[{3}]"
                    , businessCode, funeralItem.getDeadName()
                    , DataUtil.getPlainString(businessCharge.getItemCharge()), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, chargeLogTypeCode
                    , builder.toString(), JacksonUtil.obj2Json(data.getCharges().getGoodsServices()), null, JacksonUtil.obj2Json(chargeEntities));
        }

        // 删除费用总金额
        if (DataUtil.valid(deleteEntities)) {
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItemEntity chargeEntity : deleteEntities) {
                sumCharge = sumCharge.add(chargeEntity.getItemCharge());
            }
            // 删除物品服务费用日志
            builder.clear();
            builder.format("保存火化信息删除物品服务，业务编码[{0}]，逝者姓名[{1}]，删除物品服务总金额[{2}]"
                    , businessCode, funeralItem.getDeadName(), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, operationLogCode.getChargeDelete()
                    , builder.toString(), null, JacksonUtil.obj2Json(deleteEntities), null);
        }
    }

    /**
     * 依据状态等设置默认值
     *
     * @param entity 数据实体
     * @return
     * @author LiCongLu
     * @date 2020-02-17 20:00
     */
    private void saveCremationValue(CremationData data, CremationEntity entity) throws ActionException {
        Date nowDate = nowDate();
        // 判断预约状态
        if (DataUtil.valid(data.getAsAppointment())) {
            // 预约时间段不能为空
            if (DataUtil.invalid(data.getAppointmentTimeSegment())) {
                throw exception("预约火化时，预约时间段不能为空！");
            }
        } else {
            // 非预约状态时，预约时间段为空
            data.setAppointmentTimeSegment("");
        }

        if (DataUtil.invalid(entity.getProcessStateCode())) {
            // 默认未入炉
            entity.setProcessStateCode(cremationStatusCode.getYiYuDing());
        }
    }

    /**
     * 更新火化信息
     *
     * @param userItem    当前帐号
     * @param funeralItem 殡葬业务
     * @param data        更新火化信息
     * @return
     * @author LiCongLu
     * @date 2020-02-15 10:59
     */
    private void updateCremation(UserItem userItem, FuneralBusinessViewItem funeralItem, CremationData data) throws ActionException {
        // 验证主键和数据版本是否存在
        if (DataUtil.isNull(data.getId(), data.getVersion())) {
            throw exception("请求火化信息主键与版本号不能为空");
        }

        // 判断火化费用
        ChargeItem businessCharge = data.getCharges().getBusinessCharge();
        if (DataUtil.invalid(businessCharge.getId())) {
            throw exception("请求火化费用主键不能为空");
        }

        // 通过主键获取火化信息
        CremationEntity entity = cremationMapper.getCremationById(data.getId());
        if (DataUtil.isNull(entity) || DataUtil.isNull(entity.getId(), entity.getVersion())) {
            throw exception("火化主键错误，不存在此火化信息");
        }

        // 验证业务编码
        if (!data.getBusinessCode().equals(entity.getBusinessCode())) {
            throw exception(MessageConst.BUSINESS_CODE_ERROR);
        }

        // 验证火化信息版本
        if (!DataUtil.equals(data.getVersion(), entity.getVersion())) {
            throw exception(versionError("火化信息"));
        }

        // 验证是否激活状态
        if (DataUtil.isNull(entity.getAsActive())) {
            throw exception("此火化任务已非激活状态");
        }

        // 验证业务与业务费用是否匹配
        if (businessCharge.getId().intValue() != entity.getChargeId().intValue()
                || !businessCharge.getBusinessCode().equals(entity.getBusinessCode())) {
            throw exception("业务费用与业务不匹配");
        }

        // 依照状态等设置默认值
        saveCremationValue(data, entity);

        // 覆盖请求数据
        BeanUtil.copy2Bean(data, entity);

        // 更新业务费用
        businessCharge.setBusinessCode(entity.getBusinessCode())
                .setRandomCode(entity.getRandomCode())
                .setItemNumber(data.getRuleNumber())
                .setItemUnit(data.getRuleUnit())
                .setAsUnsettled(0)
                .setId(entity.getChargeId());

        String dictCode = EDictCode.FURNACE_TYPE.getCode();
        String purpose = PurposeConst.YI_TI_HUO_HUA;
        chargeWrapper.updateBusinessCharge(userItem, businessCharge, dictCode, data.getFurnaceTypeCode(), purpose, data.getRuleRemark());

        // 业务费用主键
        Integer businessChargeId = businessCharge != null ? businessCharge.getId() : 0;

        // 更新物品服务
        ArrayList<ChargeItemEntity> chargeEntities = chargeWrapper.updateGoodsServices(userItem, entity.getBusinessCode(), entity.getRandomCode(), EBusinessType.USE_IN_CREMATION.getType(), businessChargeId, data.getCharges().getGoodsServices());

        // 删除物品服务
        ArrayList<ChargeItemEntity> deleteEntities = chargeWrapper.deleteGoodsServices(userItem, entity.getBusinessCode(), entity.getRandomCode(), EBusinessType.USE_IN_CREMATION.getType(), data.getCharges().getDeleteIds());

        // 明确激活状态
        entity.setAsActive(1);

        // 设置修改帐号
        entity.setModifiedUserId(userItem.getId());
        // 更新火化信息
        cremationMapper.updateCremation(entity);

        // 更新逝者遗体类型
        funeralDeadDao.updateForCremationTypeCode(data.getCremationTypeCode(), funeralItem.getDeadId(), funeralItem.getBusinessCode(), userItem.getId());

        // 添加业务及操作日志
        Integer logTypeCode = operationLogCode.getCremationUpdate();
        Integer chargeLogTypeCode = operationLogCode.getChargeUpdate();
        saveCremationLog(userItem, funeralItem, data, entity, logTypeCode, chargeLogTypeCode, businessCharge, chargeEntities, deleteEntities);
    }

    /**
     * 从cremation表中删除指定id的火化任务信息记录
     *
     * @param data 主键和版本号
     * @return
     * @author LiCongLu
     * @date 2020-02-15 19:17
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult deleteCremationWithId(UserItem userItem, IdVersionData data) throws ActionException {
        // 通过主键获取火化信息
        CremationViewItem loadItem = cremationDao.getCremationViewById(data.getId());
        if (DataUtil.isNull(loadItem) || DataUtil.isNull(loadItem.getId(), loadItem.getVersion())) {
            return failure("主键错误，不存在此火化业务");
        }

        // 验证火化信息版本
        if (!DataUtil.equals(loadItem.getVersion(), data.getVersion())) {
            return failure(versionError("火化信息"));
        }

        // 验证是否激活状态
        if (DataUtil.invalid(loadItem.getAsActive())) {
            return failure("此火化任务已非激活状态不能删除");
        }

        // 验证状态，火化中、冷却中、火化完成等状态不能删除
        if (DataUtil.inIntegers(loadItem.getProcessStateCode()
                , cremationStatusCode.getHuoHuaRuLu()
                , cremationStatusCode.getHuoHuaWanCheng()
                , cremationStatusCode.getLengQueWanCheng()
        ,cremationStatusCode.getHuoHuaZhuangHui())) {
            return failure("火化入炉、火化完成、冷却完成、火化装灰等状态不能删除");
        }

        // 记录费用主键
        ArrayList<Integer> chargeIds = new ArrayList<>();
        // 判断业务费用是否存在
        ChargeItem businessCharge = chargeItemDao.getChargeItemById(loadItem.getChargeId());
        if (businessCharge != null) {
            // 判断是否结算
            if (DataUtil.valid(businessCharge.getAsSettled())) {
                return failure("火化业务费用已经结算，无法进行删除");
            }
            chargeIds.add(businessCharge.getId());
        }

        // 业务费用主键
        Integer businessChargeId = businessCharge != null ? businessCharge.getId() : 0;

        // 判断是否已经存在结算
        ArrayList<ChargeItem> goodsServices = chargeItemDao.listChargeItemByRandomCode(loadItem.getBusinessCode(), loadItem.getRandomCode(), businessChargeId);
        if (DataUtil.valid(goodsServices)) {
            for (ChargeItem chargeItem : goodsServices) {
                if (DataUtil.valid(chargeItem.getAsSettled())) {
                    return failure("火化物品服务已经结算，无法进行删除");
                }
                chargeIds.add(chargeItem.getId());
            }
        }

        // 删除费用
        if (chargeIds.size() > 0) {
            chargeItemDao.deletedForChargeItem(loadItem.getBusinessCode(), chargeIds, userItem.getId());
        }

        // 删除业务任务
        cremationMapper.deletedForCremation(loadItem.getId(), userItem.getId(), loadItem.getVersion());

        // 删除日志信息
        deleteCremationLog(userItem, loadItem, businessCharge, goodsServices);

        return success("删除完成");
    }

    /**
     * 删除火化日志
     *
     * @param userItem       当前账号
     * @param loadItem       火化任务
     * @param businessCharge 业务费用
     * @param goodsServices  物品服务
     * @return
     * @author LiCongLu
     * @date 2020-02-25 19:57
     */
    private void deleteCremationLog(UserItem userItem, CremationItem loadItem, ChargeItem businessCharge, ArrayList<ChargeItem> goodsServices) throws ActionException {
        // 添加业务日志及操作日志
        String businessCode = loadItem.getBusinessCode();
        Integer typeCode = businessLogCode.getCremationDelete();
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);
        // 火化日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("删除火化信息，业务编码[{0}]，操作人员[{1}]", businessCode, userItem.getFullName());
        // 添加日志
        Integer logTypeCode = operationLogCode.getCremationDelete();
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode, builder.toString(), null, JacksonUtil.obj2Json(loadItem), null);

        // 累计费用总金额
        if (DataUtil.valid(goodsServices)) {
            Integer chargeLogTypeCode = operationLogCode.getChargeDelete();
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItem chargeItem : goodsServices) {
                sumCharge = sumCharge.add(chargeItem.getItemCharge());
            }
            // 记录业务费用
            goodsServices.add(businessCharge);
            // 添加物品服务费用日志
            builder.clear();
            builder.format("删除火化信息物品服务，业务编码[{0}]，火化费用[{1}]，物品服务总金额[{2}]", businessCode
                    , DataUtil.getPlainString(businessCharge.getItemCharge()), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, chargeLogTypeCode
                    , builder.toString(), null, JacksonUtil.obj2Json(goodsServices), null);
        }
    }


    /**
     * 加载火化预约时间段
     *
     * @param data 火化预约日期
     * @return
     * @author LiCongLu
     * @date 2020-03-08 15:30
     */
    public BaseResult<ArrayList<AppointmentTimeSegmentCountItem>> loadAppointmentTimeSegmentWithDate(AppointmentTimeSegmentData data) {
        ArrayList<AppointmentTimeSegmentCountItem> loadItems = cremationTimeSegmentDao.listAppointmentTimeSegmentCountByDate(data.getFurnaceTypeCode(), data.getAppointmentDate());
        return successList(loadItems);
    }

    /**
     * 根据火化炉类型加载火化炉信息
     *
     * @param data 火化炉类型值
     * @return
     * @author LiCongLu
     * @date 2020-02-16 12:29
     */
    public BaseResult<ArrayList<CremationFurnaceViewItem>> loadCremationFurnaceWithType(DataCodeData data) {
        ArrayList<CremationFurnaceViewItem> loadItems = cremationFurnaceDao.listCremationFurnaceViewByDictCode(EDictCode.FURNACE_TYPE.getCode(), data.getTypeCode());

        // 返回响应结果
        return successList(loadItems);
    }

    /**
     * 火化服务洽谈，界面权限验证及基础数据加载
     *
     * @param data 加载全部数据
     * @return
     * @author LiCongLu
     * @date 2020-02-16 11:54
     */
    public BaseResult<CremationAllLoadData> loadCremationAll(CremationAllData data) {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            return failure(MessageConst.NO_FUNERAL_CODE);
        }

        CremationAllLoadData allLoadData = new CremationAllLoadData();

        // 加载业务数据
        if (DataUtil.valid(data.getCremationId())) {
            // 查询业务信息
            CremationViewItem loadItem = cremationDao.getCremationViewById(data.getCremationId());
            if (DataUtil.noNullOrEmpty(loadItem)) {
                // 验证业务编码
                if (!businessCode.equals(loadItem.getBusinessCode())) {
                    return failure(MessageConst.BUSINESS_CODE_ERROR);
                }
                CremationData loadData = loadCremationData(loadItem);

                allLoadData.setCremation(loadData);
            }
        }

        // 加载显示逝者部分信息
        // 火化遗体类型
        FuneralDeadItem funeralDeadItem = funeralDeadDao.getFuneralDeadByBusinessCode(businessCode);
        allLoadData.setFuneralDead(BeanUtil.copy2Bean(funeralDeadItem, new CremationAllDeadData()));
        // 设置字典文本
        dictionaryWrapper.resetDataText(allLoadData.getFuneralDead());

        // 加载字典数据
        allLoadData.setDicts(dictionaryService.loadDictionaryMap(data.getDictTypeCodes()));

        // 加载服务规则
        String dictCode = EDictCode.FURNACE_TYPE.getCode();
        allLoadData.setRuleItems(serviceItemDao.listServiceDictionaryRuleByDictCode(dictCode, ""));

        // 记载物品服务
        if (DataUtil.valid(data.getServiceItemTypeCode())) {
            String businessType = EBusinessType.USE_IN_CREMATION.getType();
            ArrayList<ServiceItem> serviceItems = serviceItemDao.listServiceItemByBusinessType(businessType);
            HashMap<String, ArrayList<ServiceItem>> dataMap = new HashMap<>(16);
            dataMap.put(businessType, serviceItems);
            allLoadData.setServiceItems(dataMap);
        }

        // 返回响应结果
        return successData(allLoadData);
    }
}
